﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.ServiceModel;
using System.Net;
using System.ServiceModel.Security;

namespace XRMServiceLibrary
{
    public class EmailLogger : BaseLogger
    {

        public static string ExceptionType = string.Empty;
        public static string Message = string.Empty;
        public static string strLogFilePath = string.Empty;
        private string ApplicationStartTime = DateTime.Now.ToString();
        private static string ApplicationName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;

        /// <summary>
        /// LogError
        /// </summary>
        /// <param name="ex"></param>
        public static bool LogError(FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> ex)
        {
            bool bReturn = false;
            // Display the details of the inner exception.
            if (ex != null)
            {
                try
                {
                    String EmailBody = string.Empty;
                    ExceptionType = ex.GetType().ToString();
                    Message = ex.Detail.Message;
                    EmailBody = EmailBody + Environment.NewLine + "<b>Exception Type : </b>" + ex.GetType().ToString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Source         : </b>" + ex.Source.ToString().Trim() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Method         : </b>" + ex.TargetSite.Name.ToString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Date           : </b>" + DateTime.Now.ToLongTimeString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Time           : </b>" + DateTime.Now.ToShortDateString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Computer       : </b>" + Dns.GetHostName().ToString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Error          : </b>" + ex.Message.ToString().Trim() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Stack Trace    : </b>" + ex.StackTrace.ToString().Trim() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Timestamp      : </b>" + ex.Detail.Timestamp + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Code           : </b>" + ex.Detail.ErrorCode + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Plugin Trace   : </b>" + ex.Detail.TraceText + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Inner Fault    : </b>" + (null == ex.Detail.InnerFault ? "Has Inner Fault" : "No Inner Fault");
                    bReturn = true;
                    FormatMailBody(EmailBody);
                }
                catch (Exception)
                {
                    bReturn = false;
                }
            }
            return bReturn;
        }

        /// <summary>
        /// LogError
        /// </summary>
        /// <param name="ex"></param>
        public static bool LogError(System.TimeoutException ex)
        {

            bool bReturn = false;
            // Display the details of the inner exception.
            if (ex != null)
            {
                ExceptionType = ex.GetType().ToString();
                Message = ex.InnerException.ToString();

                string strException = string.Empty;
                try
                {
                    String EmailBody = string.Empty;
                    ExceptionType = ex.GetType().ToString();
                    Message = ex.Message;
                    EmailBody = EmailBody + Environment.NewLine + "<b>Exception Type : </b>" + ex.GetType().ToString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Source         : </b>" + ex.Source.ToString().Trim() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Method         : </b>" + ex.TargetSite.Name.ToString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Date           : </b>" + DateTime.Now.ToLongTimeString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Time           : </b>" + DateTime.Now.ToShortDateString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Computer       : </b>" + Dns.GetHostName().ToString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Error          : </b>" + ex.Message.ToString().Trim() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Stack Trace    : </b>" + ex.StackTrace.ToString().Trim() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Inner Fault    : </b>" + (null == ex.InnerException.Message ? "Has Inner Fault" : "No Inner Fault");
                    bReturn = true;
                    FormatMailBody(EmailBody);
                }
                catch (Exception)
                {
                    bReturn = false;
                }
            }
            return bReturn;
        }

        /// <summary>
        /// LogError
        /// </summary>
        /// <param name="ex"></param>
        public static bool LogError(System.Exception ex)
        {
            bool bReturn = false;
            // Display the details of the inner exception.
            if (ex.InnerException != null)
            {

                FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> fe = ex.InnerException
                    as FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>;
                ExceptionType = ex.GetType().ToString();
                Message = ex.InnerException.ToString();

                try
                {
                    String EmailBody = string.Empty;
                    ExceptionType = ex.GetType().ToString();
                    Message = ex.Message;
                    EmailBody = EmailBody + Environment.NewLine + "<b>Exception Type : </b>" + ex.GetType().ToString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Source         : </b>" + ex.Source.ToString().Trim() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Method         : </b>" + ex.TargetSite.Name.ToString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Date           : </b>" + DateTime.Now.ToLongTimeString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Time           : </b>" + DateTime.Now.ToShortDateString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Computer       : </b>" + Dns.GetHostName().ToString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Error          : </b>" + ex.Message.ToString().Trim() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Stack Trace    : </b>" + ex.StackTrace.ToString().Trim() + "</br>";

                    if (fe != null)
                    {
                        EmailBody = EmailBody + Environment.NewLine + "<b>InnerException : </b>" + ex.InnerException.Message + "</br>";
                        EmailBody = EmailBody + Environment.NewLine + "<b>Timestamp      : </b>" + fe.Detail.Timestamp + "</br>";
                        EmailBody = EmailBody + Environment.NewLine + "<b>Code           : </b>" + fe.Detail.ErrorCode + "</br>";
                        EmailBody = EmailBody + Environment.NewLine + "<b>Message        : </b>" + fe.Detail.Message + "</br>";
                        EmailBody = EmailBody + Environment.NewLine + "<b>Plugin Trace   : </b>" + fe.Detail.TraceText + "</br>";
                        EmailBody = EmailBody + Environment.NewLine + "<b>Inner Fault    : </b>" + (null == fe.Detail.InnerFault ? "Has Inner Fault" : "No Inner Fault");
                    }
                    FormatMailBody(EmailBody);
                    bReturn = true;
                }
                catch (Exception)
                {
                    bReturn = false;
                }
            }
            return bReturn;
        }

        /// <summary>
        /// LogError
        /// </summary>
        /// <param name="ex"></param>
        public static bool LogError(ExpiredSecurityTokenException ex)
        {
            bool bReturn = false;
            // Display the details of the inner exception.
            if (ex != null)
            {

                FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> fe = ex.InnerException
                    as FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>;

                ExceptionType = ex.GetType().ToString();
                Message = ex.InnerException.ToString();

                string strException = string.Empty;
                try
                {
                    String EmailBody = string.Empty;
                    ExceptionType = ex.GetType().ToString();
                    Message = ex.Message;
                    EmailBody = EmailBody + Environment.NewLine + "<b>Exception Type : </b>" + ex.GetType().ToString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Source         : </b>" + ex.Source.ToString().Trim() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Method         : </b>" + ex.TargetSite.Name.ToString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Date           : </b>" + DateTime.Now.ToLongTimeString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Time           : </b>" + DateTime.Now.ToShortDateString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Computer       : </b>" + Dns.GetHostName().ToString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Error          : </b>" + ex.Message.ToString().Trim() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Stack Trace    : </b>" + ex.StackTrace.ToString().Trim() + "</br>";

                    if (fe != null)
                    {
                        EmailBody = EmailBody + Environment.NewLine + "<b>InnerException : </b>" + ex.InnerException.Message + "</br>";
                        EmailBody = EmailBody + Environment.NewLine + "<b>Timestamp      : </b>" + fe.Detail.Timestamp + "</br>";
                        EmailBody = EmailBody + Environment.NewLine + "<b>Code           : </b>" + fe.Detail.ErrorCode + "</br>";
                        EmailBody = EmailBody + Environment.NewLine + "<b>Message        : </b>" + fe.Detail.Message + "</br>";
                        EmailBody = EmailBody + Environment.NewLine + "<b>Plugin Trace   : </b>" + fe.Detail.TraceText + "</br>";
                        EmailBody = EmailBody + Environment.NewLine + "<b>Inner Fault    : </b>" + (null == fe.Detail.InnerFault ? "Has Inner Fault" : "No Inner Fault");
                    }
                    FormatMailBody(EmailBody);
                    bReturn = true;
                }
                catch (Exception)
                {
                    bReturn = false;
                }
            }
            return bReturn;
        }

        /// <summary>
        /// LogError
        /// </summary>
        /// <param name="ex"></param>
        public static bool LogError(SecurityAccessDeniedException ex)
        {
            bool bReturn = false;
            // Display the details of the inner exception.
            if (ex != null)
            {

                FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> fe = ex.InnerException
                    as FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>;

                ExceptionType = ex.GetType().ToString();
                Message = ex.InnerException.ToString();

                string strException = string.Empty;
                try
                {
                    String EmailBody = string.Empty;
                    ExceptionType = ex.GetType().ToString();
                    Message = ex.Message;
                    EmailBody = EmailBody + Environment.NewLine + "<b>Exception Type : </b>" + ex.GetType().ToString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Source         : </b>" + ex.Source.ToString().Trim() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Method         : </b>" + ex.TargetSite.Name.ToString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Date           : </b>" + DateTime.Now.ToLongTimeString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Time           : </b>" + DateTime.Now.ToShortDateString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Computer       : </b>" + Dns.GetHostName().ToString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Error          : </b>" + ex.Message.ToString().Trim() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Stack Trace    : </b>" + ex.StackTrace.ToString().Trim() + "</br>";

                    if (fe != null)
                    {
                        EmailBody = EmailBody + Environment.NewLine + "<b>InnerException : </b>" + ex.InnerException.Message + "</br>";
                        EmailBody = EmailBody + Environment.NewLine + "<b>Timestamp      : </b>" + fe.Detail.Timestamp + "</br>";
                        EmailBody = EmailBody + Environment.NewLine + "<b>Code           : </b>" + fe.Detail.ErrorCode + "</br>";
                        EmailBody = EmailBody + Environment.NewLine + "<b>Message        : </b>" + fe.Detail.Message + "</br>";
                        EmailBody = EmailBody + Environment.NewLine + "<b>Plugin Trace   : </b>" + fe.Detail.TraceText + "</br>";
                        EmailBody = EmailBody + Environment.NewLine + "<b>Inner Fault    : </b>" + (null == fe.Detail.InnerFault ? "Has Inner Fault" : "No Inner Fault");
                    }
                    FormatMailBody(EmailBody);
                    bReturn = true;
                }
                catch (Exception)
                {
                    bReturn = false;
                }
            }
            return bReturn;
        }

        /// <summary>
        /// LogError
        /// </summary>
        /// <param name="ex"></param>
        public static bool LogError(MessageSecurityException ex)
        {
            bool bReturn = false;
            // Display the details of the inner exception.
            if (ex != null)
            {

                FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> fe = ex.InnerException
                    as FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>;

                ExceptionType = ex.GetType().ToString();
                Message = ex.InnerException.ToString();

                string strException = string.Empty;
                try
                {
                    String EmailBody = string.Empty;
                    ExceptionType = ex.GetType().ToString();
                    Message = ex.Message;
                    EmailBody = EmailBody + Environment.NewLine + "<b>Exception Type : </b>" + ex.GetType().ToString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Source         : </b>" + ex.Source.ToString().Trim() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Method         : </b>" + ex.TargetSite.Name.ToString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Date           : </b>" + DateTime.Now.ToLongTimeString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Time           : </b>" + DateTime.Now.ToShortDateString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Computer       : </b>" + Dns.GetHostName().ToString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Error          : </b>" + ex.Message.ToString().Trim() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Stack Trace    : </b>" + ex.StackTrace.ToString().Trim() + "</br>";

                    if (fe != null)
                    {
                        EmailBody = EmailBody + Environment.NewLine + "<b>InnerException : </b>" + ex.InnerException.Message + "</br>";
                        EmailBody = EmailBody + Environment.NewLine + "<b>Timestamp      : </b>" + fe.Detail.Timestamp + "</br>";
                        EmailBody = EmailBody + Environment.NewLine + "<b>Code           : </b>" + fe.Detail.ErrorCode + "</br>";
                        EmailBody = EmailBody + Environment.NewLine + "<b>Message        : </b>" + fe.Detail.Message + "</br>";
                        EmailBody = EmailBody + Environment.NewLine + "<b>Plugin Trace   : </b>" + fe.Detail.TraceText + "</br>";
                        EmailBody = EmailBody + Environment.NewLine + "<b>Inner Fault    : </b>" + (null == fe.Detail.InnerFault ? "Has Inner Fault" : "No Inner Fault");
                    }
                    FormatMailBody(EmailBody);
                    bReturn = true;
                }
                catch (Exception)
                {
                    bReturn = false;
                }
            }
            return bReturn;
        }

        /// <summary>
        /// LogError
        /// </summary>
        /// <param name="ex"></param>
        public static bool LogError(SecurityNegotiationException ex)
        {
            bool bReturn = false;
            // Display the details of the inner exception.
            if (ex != null)
            {

                FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> fe = ex.InnerException
                    as FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>;

                ExceptionType = ex.GetType().ToString();
                Message = ex.InnerException.ToString();

                try
                {
                    String EmailBody = string.Empty;
                    ExceptionType = ex.GetType().ToString();
                    Message = ex.Message;
                    EmailBody = EmailBody + Environment.NewLine + "<b>Exception Type : </b>" + ex.GetType().ToString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Source         : </b>" + ex.Source.ToString().Trim() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Method         : </b>" + ex.TargetSite.Name.ToString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Date           : </b>" + DateTime.Now.ToLongTimeString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Time           : </b>" + DateTime.Now.ToShortDateString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Computer       : </b>" + Dns.GetHostName().ToString() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Error          : </b>" + ex.Message.ToString().Trim() + "</br>";
                    EmailBody = EmailBody + Environment.NewLine + "<b>Stack Trace    : </b>" + ex.StackTrace.ToString().Trim() + "</br>";

                    if (fe != null)
                    {
                        EmailBody = EmailBody + Environment.NewLine + "<b>InnerException : </b>" + ex.InnerException.Message + "</br>";
                        EmailBody = EmailBody + Environment.NewLine + "<b>Timestamp      : </b>" + fe.Detail.Timestamp + "</br>";
                        EmailBody = EmailBody + Environment.NewLine + "<b>Code           : </b>" + fe.Detail.ErrorCode + "</br>";
                        EmailBody = EmailBody + Environment.NewLine + "<b>Message        : </b>" + fe.Detail.Message + "</br>";
                        EmailBody = EmailBody + Environment.NewLine + "<b>Plugin Trace   : </b>" + fe.Detail.TraceText + "</br>";
                        EmailBody = EmailBody + Environment.NewLine + "<b>Inner Fault    : </b>" + (null == fe.Detail.InnerFault ? "Has Inner Fault" : "No Inner Fault");
                    }
                    FormatMailBody(EmailBody);
                    bReturn = true;
                }
                catch (Exception)
                {
                    bReturn = false;
                }
            }
            return bReturn;
        }

        /// <summary>
        /// FormatMailBody
        /// </summary>
        private static void FormatMailBody(string EmailBody)
        {

            string id = string.Empty;
            id = "-NA-";
            // Create the MailMessage object
            String Body = string.Format(@"
                                <html>
                                    <body style='font-family:calibri;font-size:8pt'>
                                         <h4>Dear Team,</h4>                                    
                                        <h5 style='color:red;text-decoration:italic'>Error Has Occurred In Application! Please find Details below.</h5>
                                        <table cellpadding=""5"" cellspacing=""0"" border=""1"" style='font-family:calibri;font-size:9pt'>
                                            <tr>
                                                <td style=""text-align: right;font-weight: bold;background-color:#f6f6f6"">Component:</td>
                                                <td>{0}</td>
                                            </tr>
                                            <tr>
                                                <td style=""text-align: right;font-weight: bold;background-color:#f6f6f6"">User:</td>
                                                <td>{1}</td>
                                            </tr>
                                            <tr>
                                                <td style=""text-align: right;font-weight: bold;background-color:#f6f6f6"">Exception Type:</td>
                                                <td>{2}</td>
                                            </tr>
                                            <tr>
                                                <td style=""text-align: right;font-weight: bold;background-color:#f6f6f6"">Message:</td>
                                                <td>{3}</td>
                                            </tr>
                                            <tr>
                                                <td style=""text-align: right;font-weight: bold;background-color:#f6f6f6"">Error Details:</td>
                                                <td>{4}</td>
                                            </tr>                                             
                                        </table>
                                        </br>
                                        Thanks & Regards, </br>
                                        TraCE Automation System                                                                                                                        
                                    </body>
                                </html>",
                ApplicationName,
                id,
                ExceptionType,
                Message,
                EmailBody);
            SendSMTPMailer objMailSent = new SendSMTPMailer();
            try
            {
                //if user doesnot provide Mailto And MailCC then both are set to default mailids.
                if (string.IsNullOrEmpty(MailTO) && string.IsNullOrEmpty(MailCC))
                {
                    MailTO = _defaultMailTO;
                    MailCC = _defaultMailCC;
                }
                objMailSent.SentMail(MailTO, EmailSubject, Body, "", "", MailCC, MailBcc);

            }
            catch
            {
                //Remain Silent
            }
        }
    }
}
